
var calculator: (strs: string) => number | undefined = function (strs) {
    //声明符号栈和数字栈
    const operators: string[] = [];
    const nums: number[] = [];
    //遍历每个字符
    for (let str of strs) {
        //普通运算符就直接入栈
        if (str === "+" || str === "-") {
            operators.push(str);
        } else if (str === "*" || str === "/") {
            operators.push(str);
        } else if (str === "(") {
            continue;
            //如果是右括号就要弹出符号栈
        } else if (str === ")") {
            let signal = <string>operators.pop();
            let currRes = <number>nums.pop();
            //依据弹出的操作符做相应计算操作
            if (signal === "+") {
                currRes = <number>nums.pop() + currRes;
            } else if (signal === '-') {
                currRes = <number>nums.pop() - currRes;
            } else if (signal === '*') {
                currRes = <number>nums.pop() * currRes;
            } else if (signal === '/') {
                currRes = <number>nums.pop() / currRes;
            }
            //将新计算出来的结果入栈
            nums.push(currRes);
        } else {
            //如果是数字就直接转换类型并入栈
            nums.push(parseInt(str));
        }
    }
    //最后数字栈中剩余的那个数就是结果
    return nums.pop();
};

console.log(calculator('((1+2)*(2+3))'));
console.log(calculator('(1+((2+3)*(4*5)))'));
console.log(calculator('(1+(3*(4/2)))'));
console.log(calculator('((2*3)+((5-1)/(6/3)))'));
console.log(calculator('(2)'));

// 因为题目中限定了所有的运算顺序都会用小括号标出，围绕着这点我们就可以做文章....
// 作为例题也是有经典解法考究的，简单来说就是可以利用双栈来实现
// 我们需要建立两个栈：运算符栈和操作数栈
// 表达式只会由括号、运算符、操作数组成，对输入字符串遍历，
// 对操作数则将其压入操作数栈。
// 运算符则将其压入运算符栈，
// 对于左括号我们忽略，
// 遇到右括号时我们弹出一个运算符，然后连弹两个操作数，并将操作符和运算数做计算，然后将新的计算结果压入操作数栈即可。